using System.Security.Claims;
using Gateway.Common.Enums;
using Gateway.Infrastructure.Provider.Operator;
using Gateway.IQuery.Menu;
using Gateway.IQuery.Sign;
using Gateway.IQuery.Sign.Request;
using Gateway.IQuery.Sign.Result;
using Gateway.IQuery.User;
using Gateway.UI.Api.Filters.Attributes;
using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Authorization;

namespace Gateway.UI.Api.Controllers;

/// <summary>
/// 登录使用
/// </summary>
public class SignController : BaseController
{
    private readonly ISignQuery _signQuery;
    private readonly ITokenService _tokenService;
    private readonly IMenuQuery _menuQuery;
    private readonly IOperatorProvider _operatorProvider;
    private readonly IServiceProvider _serviceProvider;
    private readonly IRedisCache _redisCache;
    private readonly ICaptcha _captcha;
    private readonly IUserQuery _userQuery;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="signQuery"></param>
    /// <param name="tokenService"></param>
    /// <param name="menuQuery"></param>
    /// <param name="operatorProvider"></param>
    /// <param name="serviceProvider"></param>
    /// <param name="captcha"></param>
    /// <param name="redisCache"></param>
    /// <param name="userQuery"></param>
    public SignController(ISignQuery signQuery, ITokenService tokenService, IMenuQuery menuQuery,
        IOperatorProvider operatorProvider, IServiceProvider serviceProvider, ICaptcha captcha, IRedisCache redisCache,
        IUserQuery userQuery)
    {
        _signQuery = signQuery;
        _tokenService = tokenService;
        _menuQuery = menuQuery;
        _operatorProvider = operatorProvider;
        _serviceProvider = serviceProvider;
        _captcha = captcha;
        _redisCache = redisCache;
        _userQuery = userQuery;
    }

    /// <summary>
    /// 密码登录
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    [HttpPost, Route("password"), AllowAnonymous]
    public async Task<LoginResult> Sign(LoginPasswordRequest request)
    {
        if (!string.IsNullOrEmpty(request.CheckCodeId))
        {
            if (string.IsNullOrEmpty(request.Code))
            {
                throw new MyException("请先完成验证码验证");
            }

            var checkResult = _captcha.Validate(request.CheckCodeId, request.Code);
            if (!checkResult)
            {
                throw new MyException("验证码错误");
            }
        }

        var data = await _signQuery.Sign(request);
        Claim[] claims = new Claim[1]
        {
            new Claim("roleId", data.UserInfo.RoleIds)
        };
        data.Token = await _tokenService.CreateTokenAsync(data.UserInfo.UserId, data.UserInfo.UserName, claims);
        return data;
    }

    /// <summary>
    /// 获取用户登录信息
    /// </summary>
    /// <returns></returns>
    [HttpGet, Route("user/info")]
    public async Task<LoginUserInfoResult> GetUserInfo()
    {
        var operatorId = _operatorProvider.GetOperator().OperatorId;
        return await _userQuery.GetUserLoginInfo(operatorId);
    }

    /// <summary>
    /// 获取登录人的权限
    /// </summary>
    /// <returns></returns>
    [HttpGet, Route("auth/my"), Log(logType: LogTypeEnum.GetMyAuth)]
    public async Task<UserMenuPermissionResult> GetMyAuth()
    {
        var roleIds = _operatorProvider.GetOperator()?.RoleIdList;
        if (roleIds is not { Count: > 0 })
        {
            throw new MyException("用户未配置权限菜单");
        }

        var menus = await _menuQuery.GetAuthTreeByRoleIds(roleIds);
        var permissions = await _menuQuery.GetFuncPermissionByRoleIds(roleIds);
        string userId = _operatorProvider.GetOperator().OperatorId;
        _ = Task.Factory.StartNew(async () =>
        {
            var scope = _serviceProvider.CreateScope().ServiceProvider;
            var authService = scope.GetService<IAuthService>();
            authService.CachePermissionWithOwner(permissions, userId);
            await authService.ResetApisWithOwner(userId, roleIds);
        }, TaskCreationOptions.LongRunning);
        //根据角色获取菜单权限
        var result = new UserMenuPermissionResult()
        {
            Menu = menus,
            Permissions = permissions,
            DashboardGrid = new List<string>()
            {
                "welcome",
                "ver",
                "time",
                "progress",
                "echarts",
                "about"
            }
        };
        return result;
    }


    /// <summary>
    /// 生成验证码
    /// </summary>
    /// <returns></returns>
    [HttpGet, Route("captcha"), AllowAnonymous, SkipLogger]
    public CaptchaData Generate()
    {
        string id = StringExtensions.GetSnowFlakeIdString();

        return _captcha.Generate(id);
    }

    /// <summary>
    /// 图形验证验证码
    /// </summary>
    /// <param name="id"></param>
    /// <param name="code"></param>
    /// <returns></returns>
    [Route("captcha/check"), AllowAnonymous]
    [HttpPost]
    public int Validate(string id, string code)
    {
        var data = _captcha.Validate(id, code);
        if (data)
        {
            _redisCache.Add(id, "1", TimeSpan.FromMinutes(10));
        }

        return 0;
    }

    /// <summary>
    /// 获取登录的配置
    /// </summary>
    /// <returns></returns>
    [HttpGet, Route("config"), AllowAnonymous]
    public async Task<dynamic> GetSignConfig()
    {
        return (new { secondVerEnabled = false, captchaEnabled = true });
    }

    /// <summary>
    /// 获取水印配置
    /// </summary>
    /// <returns></returns>
    [HttpGet, Route("config/watermark"), AllowAnonymous]
    public Task<dynamic> GetWatermarkConfig()
    {
        return Task.FromResult((dynamic)new { watermarkEnabled = true });
    }
}